﻿using Furion.DatabaseAccessor;
using Furion.DependencyInjection;
using Furion.DynamicApiController;
using iWare.Wms.Core;
using Mapster;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;

namespace iWare.Wms.Application
{
    /// <summary>
    /// 大屏看板服务
    /// </summary>
    [Route("api/PresentationBoard")]
    [ApiDescriptionSettings("仓库看板", Name = "PresentationBoard", Order = 100)]
    public class PresentationBoardService : ControllerBase, IDynamicApiController, ITransient
    {
        private readonly IRepository<SysConfig> _sysConfigRep;
        private readonly IRepository<WareLocation, MasterDbContextLocator> _wareLocationRep;
        private readonly IRepository<WareTask, MasterDbContextLocator> _wareTaskRep;
        private readonly IRepository<WareAssemblyWorkshop, MasterDbContextLocator> _wareAssemblyWorkshopRep;
        private readonly IRepository<WareDeviceFault, MasterDbContextLocator> _wareDeviceFaultRep;

        /// <summary>
        /// 默认
        /// </summary>
        /// <param name="sysConfigRep"></param>
        /// <param name="wareLocationRep"></param>
        /// <param name="wareTaskRep"></param>
        /// <param name="wareAssemblyWorkshopRep"></param>
        /// <param name="wareDeviceFaultRep"></param>
        public PresentationBoardService(
            IRepository<SysConfig> sysConfigRep,
            IRepository<WareLocation, MasterDbContextLocator> wareLocationRep,
            IRepository<WareTask, MasterDbContextLocator> wareTaskRep,
            IRepository<WareAssemblyWorkshop, MasterDbContextLocator> wareAssemblyWorkshopRep,
            IRepository<WareDeviceFault, MasterDbContextLocator> wareDeviceFaultRep
        )
        {
            _sysConfigRep = sysConfigRep;
            _wareLocationRep = wareLocationRep;
            _wareTaskRep = wareTaskRep;
            _wareAssemblyWorkshopRep = wareAssemblyWorkshopRep;
            _wareDeviceFaultRep = wareDeviceFaultRep;
        }

        /// <summary>
        /// 仓库介绍-基础信息
        /// </summary>
        /// <returns></returns>
        [HttpGet("WarehouseIntroduction")]
        [AllowAnonymous]
        public async Task<WarehouseIntroductionOutput> WarehouseIntroduction()
        {
            // 仓库面积
            var warehouseArea = (await _sysConfigRep.FirstOrDefaultAsync(u => u.Name.Contains("仓库面积"))).Value;

            // 总库位
            var totalStorageLocation = (await _sysConfigRep.FirstOrDefaultAsync(u => u.Name.Contains("总库位"))).Value;

            // 库区数
            var areaNum = (await _sysConfigRep.FirstOrDefaultAsync(u => u.Name.Contains("库区数"))).Value;

            // 货物种类
            var typeOfGoods = (await _sysConfigRep.FirstOrDefaultAsync(u => u.Name.Contains("货物种类"))).Value;

            // 货物使用种类
            var typeOfUse = (await _sysConfigRep.FirstOrDefaultAsync(u => u.Name.Contains("货物使用种类"))).Value;

            // 货物使用种类
            return new WarehouseIntroductionOutput
            {
                WarehouseArea = warehouseArea,
                TotalStorageLocation = totalStorageLocation,
                AreaNum = areaNum,
                TypeOfGoods = typeOfGoods,
                TypeOfUse = typeOfUse
            };
        }

        /// <summary>
        /// 仓库介绍-出入库任务
        /// </summary>
        /// <returns></returns>
        [HttpGet("GetInAndOutTask")]
        [AllowAnonymous]
        public async Task<GetInAndOutTaskOutput> GetInAndOutTask()
        {
            // 开始时间
            var start = DateTime.Now.Date.AddDays(0);

            // 结束时间
            var end = DateTime.Now.Date.AddDays(1);

            // 查询当天的任务信息
            var wareTaskList = await _wareTaskRep.DetachedEntities.Where(u => u.CreatedTime >= start && u.CreatedTime < end).ToListAsync();

            // 入库计划数
            var inPlanNum = 200;

            // 入库实际数
            var inActualNum = wareTaskList.Where(u => u.TaskType == TaskType.In).Count();

            // 出库计划数
            var outPlanNum = 180;

            // 出库实际数
            var outActualNum = wareTaskList.Where(u => u.TaskType == TaskType.Out).Count();

            return new GetInAndOutTaskOutput
            {
                InPlanNum = inPlanNum,
                InActualNum = inActualNum,
                OutPlanNum = outPlanNum,
                OutActualNum = outActualNum
            };
        }

        /// <summary>
        /// AGV库库位信息
        /// </summary>
        /// <returns></returns>
        [HttpGet("AGVLocation")]
        [AllowAnonymous]
        public async Task<WarehouseLocationOutput> AGVLocation()
        {
            // 查询平库库位
            var wareLocatioList = await _wareLocationRep.DetachedEntities.Where(u => u.AreaID == 374444736143429).ToListAsync();

            // 总库位
            var totalStorageLocation = wareLocatioList.Count;

            // 空托盘
            var emptyTray = wareLocatioList.Where(u => u.IsEmptyContainer == YesOrNot.Y && u.LocationStatus == LocationStatusEnum.cunhuo).Count();

            // 空库位
            var emptyLocation = wareLocatioList.Where(u => u.LocationStatus == LocationStatusEnum.kongxian).Count();

            // 货物/有货
            var goods = wareLocatioList.Where(u => u.IsEmptyContainer == YesOrNot.N && u.LocationStatus == LocationStatusEnum.cunhuo).Count();

            return new WarehouseLocationOutput
            {
                TotalStorageLocation = totalStorageLocation,
                EmptyTray = emptyTray,
                EmptyLocation = emptyLocation,
                Goods = goods
            };
        }

        /// <summary>
        /// 立体库库位信息
        /// </summary>
        /// <returns></returns>
        [HttpGet("SolidLocation")]
        [AllowAnonymous]
        public async Task<WarehouseLocationOutput> SolidLocation()
        {
            // 查询平库库位
            var wareLocatioList = await _wareLocationRep.DetachedEntities.Where(u => u.AreaID == 374444843716677).ToListAsync();

            // 总库位
            var totalStorageLocation = wareLocatioList.Count;

            // 空托盘
            var emptyTray = wareLocatioList.Where(u => u.IsEmptyContainer == YesOrNot.Y && u.LocationStatus == LocationStatusEnum.cunhuo).Count();

            // 空库位
            var emptyLocation = wareLocatioList.Where(u => u.LocationStatus == LocationStatusEnum.kongxian).Count();

            // 货物/有货
            var goods = wareLocatioList.Where(u => u.IsEmptyContainer == YesOrNot.N && u.LocationStatus == LocationStatusEnum.cunhuo).Count();

            return new WarehouseLocationOutput
            {
                TotalStorageLocation = totalStorageLocation,
                EmptyTray = emptyTray,
                EmptyLocation = emptyLocation,
                Goods = goods
            };
        }

        /// <summary>
        /// AGV库报警信息
        /// </summary>
        /// <returns></returns>
        [HttpGet("AGVAlarm")]
        [AllowAnonymous]
        public async Task<AGVAlarmOutput> AGVAlarm()
        {
            // 开始时间
            var start = DateTime.Now.Date.AddDays(0);

            // 结束时间
            var end = DateTime.Now.Date.AddDays(1);

            // 查询AGV-01报警信息
            var deviceFault01 = (await _wareDeviceFaultRep.DetachedEntities.Where(u => u.StartTime >= start && u.CloseTime < end && u.DeviceName.Equals("AGV-1")).ToListAsync())
                .OrderByDescending(u => u.StartTime).FirstOrDefault();
            var agv01 = new AlarmOutput()
            {
                AGVName = deviceFault01 != null ? deviceFault01.DeviceName : "AGV-1", //设备名称
                AGVStatus = deviceFault01 != null ? deviceFault01.FaultName : "正常", //AGV-01状态
                AlarmTime = deviceFault01 != null ? deviceFault01.StartTime?.ToString("HH:mm:ss") : "", //报警时间
                AlarmCode = deviceFault01 != null ? deviceFault01.FaultCode : "" //报警代码
            };

            // 查询AGV-02报警信息
            var deviceFault02 = (await _wareDeviceFaultRep.DetachedEntities.Where(u => u.StartTime >= start && u.CloseTime < end && u.DeviceName.Equals("AGV-2")).ToListAsync())
                .OrderByDescending(u => u.StartTime).FirstOrDefault();
            var agv02 = new AlarmOutput()
            {
                AGVName = deviceFault02 != null ? deviceFault02.DeviceName : "AGV-2", //设备名称
                AGVStatus = deviceFault02 != null ? deviceFault02.FaultName : "正常", //AGV-02状态
                AlarmTime = deviceFault02 != null ? deviceFault02.StartTime?.ToString("HH:mm:ss") : "", //报警时间
                AlarmCode = deviceFault02 != null ? deviceFault02.FaultCode : "" //报警代码
            };

            return new AGVAlarmOutput
            {
                AGV01 = agv01,
                AGV02 = agv02
            };
        }

        /// <summary>
        /// 立体库报警信息
        /// </summary>
        /// <returns></returns>
        [HttpGet("SolidAlarm")]
        [AllowAnonymous]
        public async Task<AlarmOutput> SolidAlarm()
        {
            // 开始时间
            var start = DateTime.Now.Date.AddDays(0);

            // 结束时间
            var end = DateTime.Now.Date.AddDays(1);

            // 查询设备信息
            var wareDeviceFault = (await _wareDeviceFaultRep.DetachedEntities.Where(u => u.StartTime >= start && u.CloseTime < end && !u.DeviceName.Contains("AGV")).ToListAsync())
                .OrderByDescending(u => u.StartTime).FirstOrDefault();

            return new AlarmOutput
            {
                AGVName = wareDeviceFault != null ? wareDeviceFault.DeviceName : "堆垛机", //设备名称
                AGVStatus = wareDeviceFault != null ? wareDeviceFault.FaultName : "正常", //堆垛机状态
                AlarmTime = wareDeviceFault != null ? wareDeviceFault.StartTime?.ToString("HH:mm:ss") : "", //报警时间
                AlarmCode = wareDeviceFault != null ? wareDeviceFault.FaultCode : "" //报警代码
            };
        }

        /// <summary>
        /// 立体库库口信息
        /// </summary>
        /// <returns></returns>
        [HttpGet("WarehouseEntrance")]
        [AllowAnonymous]
        public async Task<WarehouseEntranceOutput> WarehouseEntrance()
        {
            // 开始时间
            var start = DateTime.Now.Date.AddDays(0);

            // 结束时间
            var end = DateTime.Now.Date.AddDays(1);

            // 查询任务信息
            var wareTaskList = await _wareTaskRep.DetachedEntities.Where(u => u.CreatedTime >= start && u.CreatedTime < end && u.ContainerCode.Contains("TJ") && u.TaskStatus != TaskStatusEnum.Complete).ToListAsync();

            // 入库口
            var entrance = wareTaskList.Where(u => u.TaskType == TaskType.In).ToList().Count > 0 ? "任务" : "空闲";

            // 出库口
            var exit = wareTaskList.Where(u => u.TaskType == TaskType.Out).ToList().Count > 0 ? "任务" : "空闲";

            return new WarehouseEntranceOutput
            {
                Entrance = entrance,
                Exit = exit,
            };
        }

        /// <summary>
        /// 组装车间
        /// </summary>
        /// <returns></returns>
        [HttpGet("AssemblyWorkshop")]
        [AllowAnonymous]
        public async Task<List<AssemblyWorkshopOutput>> AssemblyWorkshop()
        {
            return await _wareAssemblyWorkshopRep.DetachedEntities.ProjectToType<AssemblyWorkshopOutput>().ToListAsync();
        }
    }
}
